package com.code.ape.codeape.common.security.component;

import cn.hutool.core.util.ArrayUtil;
import com.code.ape.codeape.common.core.constant.SecurityConstants;
import com.code.ape.codeape.common.core.entity.BaseParam;
import com.code.ape.codeape.common.security.annotation.InjectAuth;
import com.code.ape.codeape.common.security.service.CodeapeUser;
import com.code.ape.codeape.common.security.util.SecurityUtils;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.core.Ordered;

import java.util.Arrays;
import java.util.Objects;

/**
 * @author 公众号：码猿技术专栏
 * @url: www.java-family.cn
 * @description
 */
@Slf4j
@RequiredArgsConstructor
@Aspect
public class CodeapeInjectAuthAspect implements Ordered {


	@SneakyThrows
	@Around("@annotation(injectAuth) &&" +
			"(@annotation(org.springframework.web.bind.annotation.PostMapping)||" +
			"@annotation(org.springframework.web.bind.annotation.GetMapping)||" +
			"@annotation(org.springframework.web.bind.annotation.DeleteMapping)||" +
			"@annotation(org.springframework.web.bind.annotation.PutMapping)||" +
			"@annotation(org.springframework.web.bind.annotation.RequestMapping))")
	public Object around(ProceedingJoinPoint joinPoint, InjectAuth injectAuth) {
		if (injectAuth.enable()){
			CodeapeUser codeapeUser = Objects.requireNonNull(SecurityUtils.getUser());
			Object[] args = joinPoint.getArgs();
			for (int i = 0; i < args.length; i++) {
				if (!(args[i] instanceof BaseParam)) {
					continue;
				}
				BaseParam baseParam = (BaseParam) args[i];

				/**
				 * 1. web端：权限就是当前登录用户的权限
				 * 2. pda端，权限则是设备的权限+当前登录用户的权限
				 * 这里的权限取值是token中的deptAuths，这个在登录的时候就查询出来，缓存在redis中，所以这里直接用就可以
				 */
				//医院管理员+系统管理员不赋予权限
				boolean flag= ArrayUtil.contains(codeapeUser.getRoleCodes(),SecurityConstants.SYSTEM_ADMIN_CODE)
						||ArrayUtil.contains(codeapeUser.getRoleCodes(),SecurityConstants.HOS_ADMIN_CODE);
				baseParam.setDataAuth(flag?null:Arrays.asList(codeapeUser.getDeptAuths()));
				baseParam.setHosId(codeapeUser.getHosId());
				baseParam.setUserId(codeapeUser.getId());
				baseParam.setClientId(codeapeUser.getClientId());
				baseParam.setSn(codeapeUser.getSn());
			}
		}
		return joinPoint.proceed();
	}


	@Override
	public int getOrder() {
		return Ordered.HIGHEST_PRECEDENCE + 4;
	}
}
